package com.baijiaoxi.utils.qcloud;

import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.common.comm.SignVersion;
import com.baijiaoxi.common.model.cache.CloudConfigInfo;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.RemovalListener;
import com.google.common.cache.RemovalNotification;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.region.Region;

import java.util.concurrent.TimeUnit;

public class OSHelperFactory {

    private static final Cache<String, OSS> ossClientCache = CacheBuilder.newBuilder()
            .maximumSize(100) // 设置缓存最大容量
            .expireAfterAccess(30, TimeUnit.MINUTES) // 设置缓存过期时间
            .removalListener(new RemovalListener<String, OSS>() {
                @Override
                public void onRemoval(RemovalNotification<String, OSS> notification) {
                    OSS ossClient = notification.getValue();
                    if (ossClient != null)
                        ossClient.shutdown();
                }
            })
            .build();
    private static final Cache<String, COSClient> cosClientCache = CacheBuilder.newBuilder()
            .maximumSize(100) // 设置缓存最大容量
            .expireAfterAccess(30, TimeUnit.MINUTES) // 设置缓存过期时间
            .removalListener(new RemovalListener<String, COSClient>() {
                @Override
                public void onRemoval(RemovalNotification<String, COSClient> notification) {
                    COSClient cosClient = notification.getValue();
                    if (cosClient != null)
                        cosClient.shutdown();
                }
            })
            .build();

    /**
     * 不缓存ObjectStorageHelper，只缓存COSClient和OSSClient
     * 为了防止连接池忘记关闭，所以在缓存失效的时候关闭连接池
     *
     * @param cloudConfigInfo
     * @return
     */
    public static OSHelper create(CloudConfigInfo cloudConfigInfo, boolean shutdownAfterUseStat) {
        OSHelper helper;
        String cacheKey = cloudConfigInfo.getAccessKey() + ":" + cloudConfigInfo.getRegionName();
        switch (cloudConfigInfo.getProvider()) {
            case "cos":
                COSClient cosClient = cosClientCache.getIfPresent(cacheKey);
                if (cosClient == null) {
                    COSCredentials cred = new BasicCOSCredentials(cloudConfigInfo.getAccessKey(), cloudConfigInfo.getSecretKey());
                    ClientConfig clientConfig = new ClientConfig(new Region(cloudConfigInfo.getRegionName()));
                    cosClient = new COSClient(cred, clientConfig);
                    cosClientCache.put(cacheKey, cosClient);
                }
                helper = new QcloudHelper(cosClient, cloudConfigInfo.getRegionName(), cloudConfigInfo.getBucketName());
                break;
            case "oss":
                OSS oss = ossClientCache.getIfPresent(cacheKey);
                if (oss == null) {
                    ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();

                    // 显式声明使用 V4 签名算法
                    clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
                    oss = OSSClientBuilder.create()
                            .endpoint("https://" + cloudConfigInfo.getRegionName())
                            .credentialsProvider(
                                    new DefaultCredentialProvider(cloudConfigInfo.getAccessKey(),
                                            cloudConfigInfo.getSecretKey()))
                            .clientConfiguration(clientBuilderConfiguration)
                            .region(cloudConfigInfo.getRegionName()
                                    .replace("oss-", "").replace(".aliyuncs.com", ""))
                            .build();
                    ossClientCache.put(cacheKey, oss);
                }
                helper = new AliyunOSSHelper(oss, cloudConfigInfo.getRegionName(), cloudConfigInfo.getBucketName());
                break;
            default:
                return null;
        }
        if (helper != null)
            helper.setShutdownAfterUseStat(shutdownAfterUseStat);
        return helper;

    }
}
